package com.lk.util;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * author lk
 *
 * @date 2021/10/27 10:14
 * @description 生成树接口的工具类
 * @since 1.0
 */
@Slf4j
public class TreeUtil {
    private TreeUtil() {
        log.error("不能创建私有化构造器");
        throw new IllegalStateException("Utility class");
    }

    /**
     * 生成树
     *
     * @param list     数据
     * @param parentId 父id 本次设计成手动传递
     * @param <T>
     * @return 返回树结构
     */
    public static <T extends TreeNode<?>> List<T> generateTrees(List<T> list, String parentId) {
        List<T> parentTree = new ArrayList<>();
        list.stream().filter(t -> {
            if (parentId.equals(t.parentId())) {
                parentTree.add(t);
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        // 父节点的ID和子节点父ID相同则得到子节点
        parentTree.forEach(parent -> setChildren(parent, list));
        return parentTree;
    }

    /**
     * 获取子节点
     *
     * @param parent 父结构
     * @param list   数据
     * @param <T>
     */
    private static <T extends TreeNode> void setChildren(T parent, List<T> list) {
        List<T> childrenTree = new ArrayList<>();
        Object parentId = parent.id();
        list.stream().filter(children -> {
            if (Objects.equals(parentId, children.parentId())) {
                childrenTree.add(children);
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        // 如果孩子为空，则直接返回,否则继续递归设置孩子的孩子
        if (childrenTree.isEmpty()) {
            return;
        }
        parent.setChildren(childrenTree);
        // 递归设置子节点
        childrenTree.forEach(m -> setChildren(m, list));
    }
}
